package org.maxl.util;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by Administrator on 2017/3/16.
 */
public class AsyncExecutors {
    private static final Logger logger = Logger.getLogger(AsyncExecutors.class.getName());
    private static final int DEFAULT_THREADS = Runtime.getRuntime().availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() + 1 : 2;
    private static final ThreadPoolExecutor EXECUTOR_SERVICE;
    private static final int MAX_EXEC_TIME = 60;
    private static final int MAX_QUEUE_SIZE = 128;

    private AsyncExecutors() {
    }

    @Nonnull
    public static ExecutorService getExecutorService() {
        return EXECUTOR_SERVICE;
    }

    public static void exec(@Nonnull Runnable runnable) {
        Preconditions.checkNotNull(runnable);
        EXECUTOR_SERVICE.execute(runnable);
    }

    public static <E> E exec(@Nonnull Callable<E> callable) {
        Preconditions.checkNotNull(callable);
        Future future = EXECUTOR_SERVICE.submit(callable);

        try {
            return (E) future.get(60L, TimeUnit.SECONDS);
        } catch (Exception var3) {
            logger.log(Level.WARNING, "AsyncFunctions.exec error.", var3);
            return null;
        }
    }

    public static <E> List<E> execAll(@Nonnull List<Callable<E>> callableList) {
        Preconditions.checkNotNull(callableList);

        try {
            List<Future<E>> e = EXECUTOR_SERVICE.invokeAll(callableList, 60L, TimeUnit.SECONDS);
            ArrayList list = Lists.newArrayListWithCapacity(callableList.size());
            Iterator<Future<E>> i$ = e.iterator();

            while (i$.hasNext()) {
                Future<E> f = i$.next();
                if (f.isDone() && !f.isCancelled()) {
                    Object element = f.get();
                    if (element != null) {
                        list.add(element);
                    }
                }
            }

            return list;
        } catch (Exception var6) {
            logger.log(Level.WARNING, "AsyncFunctions.execAll error.", var6);
            return null;
        }
    }

    protected void finalize() throws Throwable {
        super.finalize();
        EXECUTOR_SERVICE.shutdown();
    }

    static {
        ArrayBlockingQueue<Runnable> arrayBlockingQueue = new ArrayBlockingQueue<Runnable>(128);
        EXECUTOR_SERVICE = new ThreadPoolExecutor(DEFAULT_THREADS, DEFAULT_THREADS, 60L, TimeUnit.SECONDS, arrayBlockingQueue);
        EXECUTOR_SERVICE.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        boolean jmxEnabled = Boolean.valueOf(System.getProperty("sword.jmx.enabled", "false")).booleanValue();
        if (jmxEnabled) {
            ExecutorInfo executorInfo = new ExecutorInfo();
            executorInfo.setMaxExecTime(60);
            executorInfo.setThreadPoolExecutor(EXECUTOR_SERVICE);
            MBeanExporters.registerBean(executorInfo);
        }

    }
}
